#include "GSS-db.h"
#include<string>
#include<stdlib.h>
using namespace std;

extern "C"{
int insert(ap_uint<B_size> value1[M_size], ap_uint<B_size> value2[M_size], ap_uint<B_size> value3[M_size], ap_uint<B_size> value4[M_size],
		ap_uint<B_size> value5[M_size],	ap_uint<B_size> value6[M_size], ap_uint<B_size> value7[M_size], ap_uint<B_size> value8[M_size],
		ap_uint<B_size> value9[M_size],
	    unsigned int s1[benchsize], unsigned int s2[benchsize], int buffer[benchsize], int offset, unsigned int fs[benchsize], unsigned int fd[benchsize], int fw[benchsize], int ui_cur)
{


unsigned long long multiple[16];
unsigned long long adder[16];

    multiple[0] = 1;
	multiple[1] = 5;
	multiple[2] = 25;
	multiple[3] = 125;
	multiple[4] = 625;
	multiple[5] = 3125;
	multiple[6] = 15625;
	multiple[7] = 78125;
	multiple[8] = 390625;
	multiple[9] = 1953125;
	multiple[10] = 9765625;
	multiple[11] = 48828125;
	multiple[12] = 244140625;
	multiple[13] = 1220703125;
	multiple[14] = 6103515625;
	multiple[15] = 30517578125;
	adder[0] = 0;
	adder[1] = 739;
	adder[2] = 4434;
	adder[3] = 22909;
	adder[4] = 115284;
	adder[5] = 577159;
	adder[6] = 2886534;
	adder[7] = 14433409;
	adder[8] = 72167784;
	adder[9] = 360839659;
	adder[10] = 1804199034;
	adder[11] = 9020995909;
	adder[12] = 45104980284;
	adder[13] = 225524902159;
	adder[14] = 1127624511534;
	adder[15] = 5638122558409;
#pragma HLS ARRAY_PARTITION variable=multiple complete dim=1
#pragma HLS ARRAY_PARTITION variable=adder complete dim=1


	 unsigned int insert_s[batch_size];
	 unsigned int insert_d[batch_size];
	 int insert_w[batch_size];
	 #pragma HLS ARRAY_PARTITION variable=insert_s complete dim=1
	 #pragma HLS ARRAY_PARTITION variable=insert_d complete dim=1
	 #pragma HLS ARRAY_PARTITION variable=insert_w complete dim=1


	 int candidate[batch_size][9];
#pragma HLS ARRAY_PARTITION variable=candidate complete dim=2

	for(short i=0;i<batch_size;i++)
{

	#pragma HLS UNROLL factor=100
	 insert_s[i] = 0;
	 insert_d[i] = 0;
	 insert_w[i] = 0;
}
	short size = 0;

		 for(short i =0;i<batch_size;i++)
		{
	#pragma HLS PIPELINE
			   int index = offset + i;
			   if(buffer[index]!=0){
			   bool find= false;
			   int weight = buffer[index];
			   unsigned int src = s1[index];
			   unsigned int dst = s2[index];
			   for(short j = 0;j<batch_size;j++)
			   {
				   if(src == insert_s[j]&&dst == insert_d[j])
				   {   insert_w[j] +=weight;
				   	   find = true;
				   }
			   }
			   if(!find)
			   {
				   insert_s[size] = src;
				   insert_d[size]= dst;
				   insert_w[size] = weight;
				   size=size+1;
			   }
			   }
	    }


		insert_label0:   for(short bench = 0;bench<batch_size;bench++)
		   {
	#pragma HLS PIPELINE
			 if(bench<size){
			unsigned int k1 = insert_s[bench];
		    unsigned short g1 = k1/w+1;
			unsigned short h1 = k1%w;

			unsigned int k2 = insert_d[bench];
			unsigned short g2 = k2/w+1;
			unsigned short h2 = k2%w;


			int tmp1[3];
			int tmp2[3];
			#pragma HLS ARRAY_PARTITION variable=tmp1 complete dim=1
			#pragma HLS ARRAY_PARTITION variable=tmp2 complete dim=1
			for(short i=0;i<3;i++)
			{
				tmp1[i]=((unsigned long long)g1*multiple[i]+adder[i])%bigger_p;
				tmp2[i]=((unsigned long long)g2*multiple[i]+adder[i])%bigger_p;
			}

		    for(short i=0;i<9;i++)
			{
			    short index1 = i/3;
				short index2 = i%3;
				int p1 = (h1+tmp1[index1])%w;
				int p2 = (h2+tmp2[index2])%w;

				 int pos = p1*w + p2;
				 candidate[bench][i]=pos;
			}
			}
		   }


		insert_label1:   for(short bench = 0;bench<batch_size;bench++)
		   {
		   if(bench<size)
			{
			   unsigned int k1 = insert_s[bench];
			   unsigned int k2 = insert_d[bench];

			unsigned int iw = insert_w[bench];

			unsigned short g1 = k1/w+1;
			unsigned short g2 = k2/w+1;
			short i_pos[8];
		    short f_pos[8];
		    ap_uint<B_size> tmp[9];
		    int address[9];
		    #pragma HLS ARRAY_PARTITION variable=i_pos complete dim=1
		    #pragma HLS ARRAY_PARTITION variable=f_pos complete dim=1
		    #pragma HLS ARRAY_PARTITION variable=tmp complete dim=1
		    #pragma HLS ARRAY_PARTITION variable=address complete dim=1

		      for(short i=0;i<8;i++)
		      {
		      	#pragma HLS UNROLL factor=8
		      	i_pos[i] = -1;
		      	f_pos[i] = 0;
		      }
		     for(short i=0;i<9;i++)
		    {
		    		#pragma HLS UNROLL factor=9
				address[i] = candidate[bench][i];
			}


			tmp[0] = value1[address[0]];
			tmp[1] = value2[address[1]];
			tmp[2] = value3[address[2]];
			tmp[3] = value4[address[3]];
			tmp[4] = value5[address[4]];
			tmp[5] = value6[address[5]];
			tmp[6] = value7[address[6]];
			tmp[7] = value8[address[7]];
			tmp[8] = value9[address[8]];


			 search_label:for(int i=0;i<9;i++)
			{
				   	#pragma HLS PIPELINE
					ap_uint<B_size> val = tmp[i];
					for(short j=0;j<8;j++)
					{
					 #pragma HLS UNROLL factor=8
					short index = i*8+j;
					ap_uint<64> room = val>>(j*64);
					if (room == 0)
						i_pos[j] = index;
					unsigned short src = room>>48;
					unsigned short dst = (room>>32)&0xFFFF;
					if(src == g1 && dst == g2)
						f_pos[j] = index+1;
					}
			}

		short f_pos2[2];
	 	short i_pos2[2];
	 	#pragma HLS ARRAY_PARTITION variable=i_pos2 complete dim=1
		#pragma HLS ARRAY_PARTITION variable=f_pos2 complete dim=1
	 	combinelabel0:for(short i=0;i<2;i++)
	 	{
	 		#pragma HLS UNROLL factor=2
	 		f_pos2[i] = f_pos[i*4] + f_pos[i*4+1] + f_pos[i*4+2] + f_pos[i*4+3];
	 		i_pos2[i] = -1;
	 		if(i_pos[i*4]>=0)
	 			i_pos2[i] = i_pos[i*4];
	 		else if(i_pos[i*4+1]>=0)
	 			i_pos2[i] = i_pos[i*4+1];
	 		else if(i_pos[i*4+2]>=0)
	 			i_pos2[i] = i_pos[i*4+2];
	 		else if(i_pos[i*4+3]>=0)
	 			i_pos2[i] = i_pos[i*4+3];
		}

	   short find_pos = f_pos2[0] + f_pos2[1];
	   if(find_pos>0)
	   {
			find_pos = find_pos-1;
			short index1 = find_pos/8;
			short index2 = find_pos%8;
			tmp[index1] = tmp[index1] + (((ap_uint<B_size>)iw)<<(64 * index2));


			value1[address[0]]=tmp[0];
			value2[address[1]]=tmp[1];
			value3[address[2]]=tmp[2];
			value4[address[3]]=tmp[3];
			value5[address[4]]=tmp[4];
			value6[address[5]]=tmp[5];
			value7[address[6]]=tmp[6];
			value8[address[7]]=tmp[7];
			value9[address[8]]=tmp[8];
		}
		else
		{
			short insert_pos = -1;
			if(i_pos2[0]>=0)
				insert_pos = i_pos2[0];
			else if(i_pos2[1]>=0)
				insert_pos = i_pos2[1];

			if(insert_pos>=0){

			short index1 = insert_pos/8;
			short index2 = insert_pos%8;

			ap_uint<B_size> new_bucket = 0;
			ap_uint<64> new_room = 0;
			new_room |= ((ap_uint<64>)g1)<<48;
			new_room |= ((ap_uint<64>)g2)<<32;
			new_room |= ((ap_uint<64>)iw);
			new_bucket |= ((ap_uint<B_size>)new_room)<<(64*index2);
			tmp[index1] |= new_bucket;


			value1[address[0]]=tmp[0];
			value2[address[1]]=tmp[1];
			value3[address[2]]=tmp[2];
			value4[address[3]]=tmp[3];
			value5[address[4]]=tmp[4];
			value6[address[5]]=tmp[5];
			value7[address[6]]=tmp[6];
			value8[address[7]]=tmp[7];
			value9[address[8]]=tmp[8];
			}
			else
			{
				fs[ui_cur] = k1;
				fd[ui_cur] = k2;
				fw[ui_cur] = iw;
				ui_cur++;
			}

	}
	}
	}

		return ui_cur;
}


void edge_query(ap_uint<B_size> value1[M_size], ap_uint<B_size> value2[M_size], ap_uint<B_size> value3[M_size], ap_uint<B_size> value4[M_size],
		ap_uint<B_size> value5[M_size],	ap_uint<B_size> value6[M_size], ap_uint<B_size> value7[M_size], ap_uint<B_size> value8[M_size],
		ap_uint<B_size> value9[M_size],
	    unsigned int s1[benchsize], unsigned int s2[benchsize], int buffer[benchsize], int offset)
{
unsigned long long multiple[16];
unsigned long long adder[16];

    multiple[0] = 1;
	multiple[1] = 5;
	multiple[2] = 25;
	multiple[3] = 125;
	multiple[4] = 625;
	multiple[5] = 3125;
	multiple[6] = 15625;
	multiple[7] = 78125;
	multiple[8] = 390625;
	multiple[9] = 1953125;
	multiple[10] = 9765625;
	multiple[11] = 48828125;
	multiple[12] = 244140625;
	multiple[13] = 1220703125;
	multiple[14] = 6103515625;
	multiple[15] = 30517578125;
	adder[0] = 0;
	adder[1] = 739;
	adder[2] = 4434;
	adder[3] = 22909;
	adder[4] = 115284;
	adder[5] = 577159;
	adder[6] = 2886534;
	adder[7] = 14433409;
	adder[8] = 72167784;
	adder[9] = 360839659;
	adder[10] = 1804199034;
	adder[11] = 9020995909;
	adder[12] = 45104980284;
	adder[13] = 225524902159;
	adder[14] = 1127624511534;
	adder[15] = 5638122558409;





#pragma HLS ARRAY_PARTITION variable=multiple complete dim=1
#pragma HLS ARRAY_PARTITION variable=adder complete dim=1


		query_label0:   for(short bench = 0;bench<batch_size;bench++)
		   {
	#pragma HLS PIPELINE
			int bench_cur = bench + offset;
		    unsigned short g1 = s1[bench_cur]/w+1;
			unsigned short h1 = s1[bench_cur]%w;

			unsigned short g2 = s2[bench_cur]/w+1;
			unsigned short h2 = s2[bench_cur]%w;

			int tmp1[3];
			int tmp2[3];
			#pragma HLS ARRAY_PARTITION variable=tmp1 complete dim=1
			#pragma HLS ARRAY_PARTITION variable=tmp2 complete dim=1
			for(short i=0;i<3;i++)
			{
				tmp1[i]=((unsigned long long)g1*multiple[i]+adder[i])%bigger_p;
				tmp2[i]=((unsigned long long)g2*multiple[i]+adder[i])%bigger_p;
			}
			short f_pos[72];
		    ap_uint<B_size> tmp[9];
		    int address[9];
		    #pragma HLS ARRAY_PARTITION variable=f_pos complete dim=1
		    #pragma HLS ARRAY_PARTITION variable=tmp complete dim=1
		    #pragma HLS ARRAY_PARTITION variable=address complete dim=1

		      for(short i=0;i<72;i++)
		      {
		      	#pragma HLS UNROLL factor=72
		      	f_pos[i] = 0;
		      }
		     for(short i=0;i<9;i++)
		    {
		    	#pragma HLS UNROLL factor=9
		        short index1 = i/3;
				short index2 = i%3;
				int p1 = (h1+tmp1[index1])%w;
				int p2 = (h2+tmp2[index2])%w;
				address[i] = p1*w + p2;
			}

			tmp[0] = value1[address[0]];
			tmp[1] = value2[address[1]];
			tmp[2] = value3[address[2]];
			tmp[3] = value4[address[3]];
			tmp[4] = value5[address[4]];
			tmp[5] = value6[address[5]];
			tmp[6] = value7[address[6]];
			tmp[7] = value8[address[7]];
			tmp[8] = value9[address[8]];


			 search_label:for(short i=0;i<9;i++)
			{
				#pragma HLS UNROLL factor=9
				ap_uint<B_size> val = tmp[i];
				for(short j=0;j<8;j++)
				{
					#pragma HLS UNROLL factor=8
					short index = i*8+j;
					ap_uint<64> room = val>>(j*64);
					unsigned short src = room>>48;
					unsigned short dst= (room>>32)&0xFFFF;
					if(src == g1 && dst == g2)
						f_pos[index] = index+1;
				}
			}

		short f_pos2[18];
		#pragma HLS ARRAY_PARTITION variable=f_pos2 complete dim=1
	 	combinelabel0:for(int i=0;i<18;i++)
	 	{
	 		#pragma HLS UNROLL factor=18
	 		f_pos2[i] = f_pos[i*4] + f_pos[i*4+1] + f_pos[i*4+2] + f_pos[i*4+3];
		}

		short f_pos3[6];
		#pragma HLS ARRAY_PARTITION variable=f_pos3 complete dim=1
	 	combinelabel1:for(int i=0;i<6;i++)
	 	{
	 		#pragma HLS UNROLL factor=6
	 		f_pos3[i] = f_pos2[i*3] + f_pos2[i*3+1] + f_pos2[i*3+2];
		}
		short f_pos4[2];
		#pragma HLS ARRAY_PARTITION variable=f_pos4 complete dim=1
	 	combinelabel2:for(int i=0;i<2;i++)
	 	{
	 		#pragma HLS UNROLL factor=2
	 		f_pos4[i] = f_pos3[i*3] + f_pos3[i*3+1] + f_pos3[i*3+2];
		}

	   short find_pos = f_pos4[0] + f_pos4[1];// + f_pos4[3];
	   if(find_pos>0)
	   {
		    find_pos = find_pos-1;
			short index1 = find_pos/8;
			short index2 = find_pos%8;
			int result = ((tmp[index1]>>(64*index2))&(0xFFFFFFFF));
			buffer[bench_cur] = result;
		}
		else
		{
			buffer[bench_cur] = 0;
		}
	}


	 return;

}


int successor(ap_uint<B_size> value1[M_size], ap_uint<B_size> value2[M_size], ap_uint<B_size> value3[M_size], ap_uint<B_size> value4[M_size],
		ap_uint<B_size> value5[M_size],	ap_uint<B_size> value6[M_size], ap_uint<B_size> value7[M_size], ap_uint<B_size> value8[M_size],
		ap_uint<B_size> value9[M_size],
		unsigned int s1,
		unsigned int B_buffer[buffer_size2], int offset)
{

	unsigned int M_buffer[9][8][buffer_row];

	#pragma HLS ARRAY_PARTITION variable=M_buffer complete dim=1
	#pragma HLS ARRAY_PARTITION variable=M_buffer complete dim=2

const unsigned long long multiple[16] = {1, 5, 25, 125, 625, 3125, 15625, 78125, 390625,1953125,9765625,48828125,244140625,
								  1220703125, 6103515625, 30517578125};
const unsigned long long adder[16] = {0, 739, 4434, 22909, 115284, 577159, 2886534, 14433409, 72167784, 360839659, 1804199034, 9020995909,
							45104980284, 225524902159, 1127624511534, 5638122558409};
#pragma HLS ARRAY_PARTITION variable=multiple complete dim=1
#pragma HLS ARRAY_PARTITION variable=adder complete dim=1

		int tmp1[3];
		int cur[9][8];
		unsigned int p[3];
		ap_uint<B_size> bucket[9];
		unsigned int address[9];
	#pragma HLS ARRAY_PARTITION variable=cur complete dim=1
	#pragma HLS ARRAY_PARTITION variable=cur complete dim=2
	#pragma HLS ARRAY_PARTITION variable=p complete dim=1
	#pragma HLS ARRAY_PARTITION variable=tmp1 complete dim=1
	#pragma HLS ARRAY_PARTITION variable=bucket complete dim=1
	#pragma HLS ARRAY_PARTITION variable=address complete dim=1
	unsigned short g1 = s1/w+1;
	unsigned short h1 = s1%w;
	unsigned int k1 = s1+w;


	for(short i=0;i<3;i++)
	{
    #pragma HLS UNROLL factor=3
	tmp1[i]=((unsigned long long)g1*multiple[i]+adder[i])%bigger_p;
	p[i] = (tmp1[i]+h1)%w;
	}

	for(short i=0;i<9;i++)
	{
    #pragma HLS UNROLL factor=9
    for(short j=0;j<8;j++)
    {
    	#pragma HLS UNROLL factor=8
		cur[i][j] = 0;
	}
	}

	suc_label0:for(short o=0;o<2;o++){
	for(short i=0;i<w/2;i++)
	{
		#pragma HLS PIPELINE
		short os = o*(w/2);
		for(short j=0;j<9;j++)
		{
		 #pragma HLS UNROLL factor=9
		 short r = j/3;
		 address[j] = p[r]*w + i + os;
		}
		bucket[0] = value1[address[0]];
		bucket[1] = value2[address[1]];
		bucket[2] = value3[address[2]];
		bucket[3] = value4[address[3]];
		bucket[4] = value5[address[4]];
		bucket[5] = value6[address[5]];
		bucket[6] = value7[address[6]];
		bucket[7] = value8[address[7]];
		bucket[8] = value9[address[8]];


		for(short j=0;j<9;j++){
			#pragma HLS UNROLL factor=9
			ap_uint<B_size> b_val = bucket[j];
		for(short k=0;k<8;k++)
		{
			#pragma HLS UNROLL factor=8
			ap_uint<64> row = b_val>>(64*k);
			if((row>>48)==g1)
			{
				short tmp_s = j%3;
				int tmp_g = (row>>32)&0xFFFF;
				int shifter = (tmp_g*multiple[tmp_s]+adder[tmp_s])%bigger_p;
	  			int tmp_h = i + os;
	  			int add = shifter/w;
	  			tmp_h+=add*w;
	  			if(tmp_h<shifter)
	  				tmp_h+=w;
	  			tmp_h -= shifter;
	  			M_buffer[j][k][cur[j][k]] = (tmp_g-1)*w+tmp_h;
	  			cur[j][k]++;
			}
		}
		}
	}
	}


	int index = 0;
	int curB = offset;


	for(short i=0;i<9;i++)
	{
		for(short j=0;j<8;j++)
		{
			for(int k=0;k<cur[i][j];k++)
			{
				B_buffer[curB] = M_buffer[i][j][k];
				curB++;
			}
		}
	}

	B_buffer[curB] = 0; //mark the end;
	curB++;
	return curB;
}

int precursor(ap_uint<B_size> value1[M_size], ap_uint<B_size> value2[M_size], ap_uint<B_size> value3[M_size], ap_uint<B_size> value4[M_size],
		ap_uint<B_size> value5[M_size],	ap_uint<B_size> value6[M_size], ap_uint<B_size> value7[M_size], ap_uint<B_size> value8[M_size],
		ap_uint<B_size> value9[M_size],
		unsigned int s1,
		unsigned int B_buffer[buffer_size2], int offset)
{
		unsigned int M_buffer[9][8][buffer_row];

	#pragma HLS ARRAY_PARTITION variable=M_buffer complete dim=1
	#pragma HLS ARRAY_PARTITION variable=M_buffer complete dim=2


const unsigned long long multiple[16] = {1, 5, 25, 125, 625, 3125, 15625, 78125, 390625,1953125,9765625,48828125,244140625,
								  1220703125, 6103515625, 30517578125};
const unsigned long long adder[16] = {0, 739, 4434, 22909, 115284, 577159, 2886534, 14433409, 72167784, 360839659, 1804199034, 9020995909,
							45104980284, 225524902159, 1127624511534, 5638122558409};
#pragma HLS ARRAY_PARTITION variable=multiple complete dim=1
#pragma HLS ARRAY_PARTITION variable=adder complete dim=1

	int tmp1[3];
	int cur[9][8];
	unsigned int p[3];
	ap_uint<B_size> bucket[9];
	unsigned int address[9];
	#pragma HLS ARRAY_PARTITION variable=cur complete dim=1
	#pragma HLS ARRAY_PARTITION variable=cur complete dim=2
	#pragma HLS ARRAY_PARTITION variable=p complete dim=1
	#pragma HLS ARRAY_PARTITION variable=tmp1 complete dim=1
	#pragma HLS ARRAY_PARTITION variable=bucket complete dim=1
	#pragma HLS ARRAY_PARTITION variable=address complete dim=1
	unsigned short g1 = s1/w+1;
	unsigned short h1 = s1%w;
	unsigned int k1 = s1+w;


	for(short i=0;i<3;i++)
	{
    #pragma HLS UNROLL factor=3
	tmp1[i]=((unsigned long long)g1*multiple[i]+adder[i])%bigger_p;
	p[i] = (tmp1[i]+h1)%w;
	}
	for(short i=0;i<9;i++)
	{
    #pragma HLS UNROLL factor=9
    for(short j=0;j<8;j++)
    {
    	#pragma HLS UNROLL factor=8
		cur[i][j] = 0;
	}
	}


		for(short o=0;o<2;o++){
		for(short i = 0;i<w/2;i++)
		{
		#pragma HLS PIPELINE
		short os = o*(w/2);
		for(short j=0;j<9;j++)
		{
		 #pragma HLS UNROLL factor=9
		 short r = j%3;
		 address[j] = p[r] + (i+os)*w;
		}

		bucket[0] = value1[address[0]];
		bucket[1] = value2[address[1]];
		bucket[2] = value3[address[2]];
		bucket[3] = value4[address[3]];
		bucket[4] = value5[address[4]];
		bucket[5] = value6[address[5]];
		bucket[6] = value7[address[6]];
		bucket[7] = value8[address[7]];
		bucket[8] = value9[address[8]];

		for(short j=0;j<9;j++){
		#pragma HLS UNROLL factor=9
		ap_uint<B_size> b_val = bucket[j];
		for(short k=0;k<8;k++)
		{
			#pragma HLS UNROLL factor=8
			ap_uint<64> column = (b_val>>(k*64));
			if(((column>>32)&0xFFFF)==g1)
			{
				short tmp_s = j/3;
				int tmp_g = column>>48;

			    int shifter = (tmp_g*multiple[tmp_s]+adder[tmp_s])%bigger_p;
	  		    int tmp_h = i+os;
	  			int add = shifter/w;
	  			tmp_h+=add*w;
	  			if(tmp_h<shifter)
	  			tmp_h+=w;
	  			tmp_h -= shifter;

	  		M_buffer[j][k][cur[j][k]] = (tmp_g-1)*w+tmp_h;
	  		cur[j][k]++;
			}
		}
	}
	}
		}


	int index = 0;
	int curB = offset;
	for(short i=0;i<9;i++)
		{
			for(short j=0;j<8;j++)
			{
				for(int k=0;k<cur[i][j];k++)
				{
					B_buffer[curB] = M_buffer[i][j][k];
					curB++;
				}
			}
		}


	B_buffer[curB] = 0; //mark the end;
	curB++;
	return curB;
}

void GSS(ap_uint<B_size> value1[M_size], ap_uint<B_size> value2[M_size], ap_uint<B_size> value3[M_size], ap_uint<B_size> value4[M_size],
		ap_uint<B_size> value5[M_size],	ap_uint<B_size> value6[M_size], ap_uint<B_size> value7[M_size], ap_uint<B_size> value8[M_size],
		ap_uint<B_size> value9[M_size],
	   unsigned int s1[benchsize], unsigned int s2[benchsize],  int buffer[benchsize], unsigned int B_buffer[buffer_size2], unsigned int fs[benchsize], unsigned int fd[benchsize], int fw[benchsize], int type, int size)
		{

#pragma HLS INTERFACE m_axi port=value1 offset=slave bundle=gmem0
#pragma HLS INTERFACE m_axi port=value2 offset=slave bundle=gmem1
#pragma HLS INTERFACE m_axi port=value3 offset=slave bundle=gmem2
#pragma HLS INTERFACE m_axi port=value4 offset=slave bundle=gmem3
#pragma HLS INTERFACE m_axi port=value5 offset=slave bundle=gmem4
#pragma HLS INTERFACE m_axi port=value6 offset=slave bundle=gmem5
#pragma HLS INTERFACE m_axi port=value7 offset=slave bundle=gmem6
#pragma HLS INTERFACE m_axi port=value8 offset=slave bundle=gmem7
#pragma HLS INTERFACE m_axi port=value9 offset=slave bundle=gmem8


#pragma HLS INTERFACE m_axi port=s1 offset=slave bundle=gmem9
#pragma HLS INTERFACE m_axi port=s2 offset=slave bundle=gmem10
#pragma HLS INTERFACE m_axi port=buffer offset=slave bundle=gmem11
#pragma HLS INTERFACE m_axi port=B_buffer offset=slave bundle=gmem11
#pragma HLS INTERFACE m_axi port=fs offset=slave bundle=gmem9
#pragma HLS INTERFACE m_axi port=fd offset=slave bundle=gmem10
#pragma HLS INTERFACE m_axi port=fw offset=slave bundle=gmem11


#pragma HLS INTERFACE s_axilite port=value1 bundle=control
#pragma HLS INTERFACE s_axilite port=value2 bundle=control
#pragma HLS INTERFACE s_axilite port=value3 bundle=control
#pragma HLS INTERFACE s_axilite port=value4 bundle=control
#pragma HLS INTERFACE s_axilite port=value5 bundle=control
#pragma HLS INTERFACE s_axilite port=value6 bundle=control
#pragma HLS INTERFACE s_axilite port=value7 bundle=control
#pragma HLS INTERFACE s_axilite port=value8 bundle=control
#pragma HLS INTERFACE s_axilite port=value9 bundle=control



#pragma HLS INTERFACE s_axilite port=s1 bundle=control
#pragma HLS INTERFACE s_axilite port=s2 bundle=control
#pragma HLS INTERFACE s_axilite port=buffer bundle=control
#pragma HLS INTERFACE s_axilite port=B_buffer bundle=control
#pragma HLS INTERFACE s_axilite port=fs bundle=control
#pragma HLS INTERFACE s_axilite port=fd bundle=control
#pragma HLS INTERFACE s_axilite port=fw bundle=control


#pragma HLS INTERFACE s_axilite port=type bundle=control
#pragma HLS INTERFACE s_axilite port=size bundle=control

#pragma HLS INTERFACE s_axilite port=return bundle=control

	if(type==0)
	{
		int ui_cur =0;
	for(int i=0;i<(size/batch_size);i++)
	{
		int offset = i*batch_size;
	 	ui_cur = insert(value1, value2, value3, value4, value5, value6, value7, value8, value9,
		s1, s2, buffer, offset, fs, fd, fw, ui_cur);
	}
	return;
	}
	else if(type==1)
	{
		int uf_cur = 0;
		for(int i=0;i<(size/batch_size);i++)
		{
		int offset = i*batch_size;
		edge_query(value1, value2, value3, value4, value5, value6, value7, value8, value9,
		s1, s2, buffer, offset);
	    }
		return;
	}
	else if(type==2)
	{
		int offset = 0;
		for(int i=0;i<size;i++)
		{
		offset = successor(value1, value2, value3, value4, value5, value6, value7, value8, value9,
		s1[i], B_buffer, offset);
		if(offset>=0.9*buffer_size2)
			break;
		}
		return;
	}
	else if(type==3)
	{
		int offset = 0;
		for(int i=0;i<size;i++)
		{
		offset = precursor(value1, value2, value3, value4, value5, value6, value7, value8, value9,
	    s1[i], B_buffer, offset);
		if(offset>=0.9*buffer_size2)
			break;
		}
		return;
	}
	return;
}
}
